home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
thesrc10.zip
/
UTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-11
|
57KB
|
1,732 lines
/***********************************************************************/
/* UTIL.C - Utility routines */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991,1992 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@itc.gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 7877
* QLD 4121
* Australia
*/
#include <stdio.h>
#include <stdlib.h>
#include "the.h"
/*--------------------------- common data -----------------------------*/
#define MAX_RECV 20
static unsigned char *recv[MAX_RECV];
static int recv_len[MAX_RECV];
static int add_recv=(-1);
static int retr_recv=(-1);
static int num_recv=0;
/*-------------------------- external data ----------------------------*/
extern LINE *next_line,*curr_line;
extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern char number_of_views; /* number of open files */
extern char current_file; /* pointer to current file */
extern WINDOW *foot,*error_window;
extern char error_on_screen;
extern unsigned char *rec;
extern unsigned short rec_len;
extern unsigned char mode_insert; /* defines insert mode toggle */
extern unsigned char in_profile; /* indicates if processing profile */
extern unsigned char temp_cmd[150];
/*-------------------------- function definitions ---------------------*/
#ifdef PROTO
void post_process_line(long line_number);
void pre_process_line(long line_number);
#else
void post_process_line();
void pre_process_line();
#endif
/*man***************************************************************************
NAME
memrevne - search buffer reversed for NOT character
SYNOPSIS
#include "the.h"
short memrevne(buffer,known_char,max_len)
char *buffer;
unsigned char known_char;
short max_len;
DESCRIPTION
The memrevne function searches the buffer from the right for first
character NOT equal to the supplied character.
RETURN VALUE
If successful, returns the position of first NON-matching character
or (-1) if unsuccessful.
SEE ALSO
strzrevne, strzne
*******************************************************************************/
#ifdef PROTO
short memrevne(char *buffer,unsigned char known_char,short max_len)
#else
short memrevne(buffer,known_char,max_len)
char *buffer;
unsigned char known_char;
short max_len;
#endif
{
/*--------------------------- local data ------------------------------*/
register int len=max_len;
/*--------------------------- processing ------------------------------*/
for (--len; len>=0 && buffer[len]==known_char; len--);
return(len);
}
/*man***************************************************************************
NAME
meminschr - insert character into buffer
SYNOPSIS
#include "the.h"
char *meminschr(buffer,chr,location,max_length,curr_length)
char *buffer;
unsigned char chr;
short location,max_length,curr_length;
DESCRIPTION
The meminschr inserts the supplied 'chr' into the buffer 'buffer'
before the 'location' specified. 'location' is an offset (0 based)
from the start of 'buffer'.
The 'buffer' will not be allowed to have more than 'max_length'
characters, so if the insertion of the character causes the
'max_length' to be exceeded, the last character of 'buffer' will
be lost.
RETURN VALUE
A pointer to the same 'buffer' as was supplied.
SEE ALSO
meminsstr, memdelchr
*******************************************************************************/
#ifdef PROTO
char *meminschr(char *buffer,unsigned char chr,short location,
short max_length,short curr_length)
#else
char *meminschr(buffer,chr,location,max_length,curr_length)
char *buffer;
unsigned char chr;
short location,max_length,curr_length;
#endif
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
for (i=curr_length;i > location;i--)
if (i < max_length)
buffer[i] = buffer[i-1];
if (location < max_length)
buffer[location] = chr;
return(buffer);
}
/*man***************************************************************************
NAME
meminsmem - insert string into buffer
SYNOPSIS
#include "the.h"
char *meminsmem(buffer,str,location,max_length,curr_length)
char *buffer;
char *str;
short location,max_length,curr_length;
DESCRIPTION
The meminsmem function inserts the supplied 'str' into the buffer 'buffer'
before the 'location' specified. 'location' is an offset (0 based)
from the start of 'buffer'.
The 'buffer' will not be allowed to have more than 'max_length'
characters, so if the insertion of the string causes the
'max_length' to be exceeded, the last character(s) of 'buffer' will
be lost.
RETURN VALUE
A pointer to the same 'buffer' as was supplied.
SEE ALSO
meminschr
*******************************************************************************/
#ifdef PROTO
char *meminsmem(char *buffer,char *str,short len,short location,
short max_length,short curr_length)
#else
char *meminsmem(buffer,str,len,location,max_length,curr_length)
char *buffer,*str;
short len,location,max_length,curr_length;
#endif
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
for (i=curr_length;i > location;i--)
if (i+len-1 < max_length)
buffer[i+len-1] = buffer[i-1];
for (i=0;i<len;i++)
if (location+i < max_length)
buffer[location+i] = str[i];
return(buffer);
}
/*man***************************************************************************
NAME
memdelchr - delete character(s) from buffer
SYNOPSIS
#include "the.h"
char *memdelchr(buffer,location,curr_length,num_chars)
char *buffer;
short location,curr_length,num_chars;
DESCRIPTION
The memdelchr deletes the supplied number of characters from the
buffer starting at the 'location' specified. 'location' is an offset (0 based)
from the start of 'buffer'.
For each character deleted, what was the last character in buffer;
based on 'curr_length' will be replaced with a space.
RETURN VALUE
A pointer to the same 'buffer' as was supplied.
SEE ALSO
meminschr
*******************************************************************************/
#ifdef PROTO
char *memdelchr(char *buffer,short location,short curr_length,
short num_chars)
#else
char *memdelchr(buffer,location,curr_length,num_chars)
char *buffer;
short location,curr_length,num_chars;
#endif
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
for (i=location;i <curr_length;i++)
if (i+num_chars >= curr_length)
buffer[i] = ' ';
else
buffer[i] = buffer[i+num_chars];
return(buffer);
}
/*man***************************************************************************
NAME
strzne - search string for NOT character
SYNOPSIS
#include "the.h"
short strzne(str,chr)
char *str;
unsigned char ch;
DESCRIPTION
The strzne function searches the string from the left for the first
character NOT equal to the supplied character.
RETURN VALUE
If successful, returns the position of first NON-matching character
or (-1) if unsuccessful.
SEE ALSO
strzrevne, memrevne
*******************************************************************************/
#ifdef PROTO
short strzne(char *str,unsigned char ch)
#else
short strzne(str,ch)
char *str;
unsigned char ch;
#endif
{
/*--------------------------- local data ------------------------------*/
register int len;
register int i = 0;
/*--------------------------- processing ------------------------------*/
len = strlen(str);
for (; i<len && str[i]==ch; i++);
if (i>=len)
i = (-1);
return(i);
}
/*man***************************************************************************
NAME
memne - search buffer for NOT character
SYNOPSIS
#include "the.h"
short memne(buffer,chr,length)
unsigned char *buffer;
unsigned char chr;
short length;
DESCRIPTION
The memne function searches the buffer from the left for the first
character NOT equal to the supplied character.
RETURN VALUE
If successful, returns the position of first NON-matching character
or (-1) if unsuccessful.
SEE ALSO
strzrevne, memrevne, strzne
*******************************************************************************/
#ifdef PROTO
short memne(unsigned char *buffer,unsigned char chr,short length)
#else
short memne(buffer,chr,length)
unsigned char *buffer;
unsigned char chr;
short length;
#endif
{
/*--------------------------- local data ------------------------------*/
register int i = 0;
/*--------------------------- processing ------------------------------*/
for (; i<length && buffer[i]==chr; i++);
if (i>=length)
i = (-1);
return(i);
}
/*man***************************************************************************
NAME
strzrevne - search string reversed for NOT character
SYNOPSIS
#include "the.h"
short strzrevne(str,chr)
char *str;
unsigned char ch;
DESCRIPTION
The strzrevne function searches the string from the right for the
first character NOT equal to the supplied character.
RETURN VALUE
If successful, returns the position of first NON-matching character
or (-1) if unsuccessful.
SEE ALSO
strzne, memrevne
*******************************************************************************/
#ifdef PROTO
short strzrevne(char *str,unsigned char ch)
#else
short strzrevne(str,ch)
char *str;
unsigned char ch;
#endif
{
/*--------------------------- local data ------------------------------*/
register int len;
/*--------------------------- processing ------------------------------*/
len = strlen(str);
for (--len; len>=0 && str[len]==ch; len--);
return(len);
}
/*man***************************************************************************
NAME
strzreveq - search string reversed for character
SYNOPSIS
short strzreveq(str,chr)
char *str;
unsigned char ch;
DESCRIPTION
The strzreveq function searches the string from the right for the
first character equal to the supplied character.
RETURN VALUE
If successful, returns the position of first matching character
or (-1) if unsuccessful.
SEE ALSO
strzrevne
*******************************************************************************/
#ifdef PROTO
short strzreveq(unsigned char *str,unsigned char ch)
#else
short strzreveq(str,ch)
unsigned char *str,ch;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short len;
/*--------------------------- processing ------------------------------*/
len = strlen(str);
for (--len; len>=0 && str[len]!=ch; len--);
return(len);
}
/*man***************************************************************************
NAME
strtrunc - truncate trailing spaces from string
SYNOPSIS
#include "the.h"
char *strtrunc(string)
char *string;
DESCRIPTION
The strtrunc truncates all trailing spaces from the supplied string.
RETURN VALUE
A pointer to the original string, now truncated.
SEE ALSO
*******************************************************************************/
#ifdef PROTO
char *strtrunc(char *string)
#else
char *strtrunc(string)
char *string;
#endif
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
i = strzrevne(string,' ');
if (i == (-1))
strcpy(string,"");
else
*(string+i+1) = '\0';
return(string);
}
/***********************************************************************/
#ifdef PROTO
short mempos(unsigned char *haystack,short hay_len,
unsigned char *needle,short nee_len)
#else
short mempos(haystack,hay_len,needle,nee_len)
unsigned char *haystack,*needle;
short hay_len,nee_len;
#endif
/***********************************************************************/
/* Function : Finds a needle in a haystack in a memory array. */
/* Parameters: haystack - where to find the needle */
/* hay_len - the length of the haystack */
/* needle - the needle to find */
/* nee_len - the length of the needle */
/* Return : position in haystack (0 based) or (-1) if no needle */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
for (i=0;i<(hay_len-nee_len);i++)
if (memcmp(haystack+i,needle,nee_len) == 0)
return(i);
return(-1);
}
/***********************************************************************/
#ifdef PROTO
short memposi(unsigned char *haystack,short hay_len,
unsigned char *needle,short nee_len)
#else
short memposi(haystack,hay_len,needle,nee_len)
unsigned char *haystack,*needle;
short hay_len,nee_len;
#endif
/***********************************************************************/
/* Function : Finds a needle in a haystack in a memory array; */
/* case insensitive. */
/* Parameters: haystack - where to find the needle */
/* hay_len - the length of the haystack */
/* needle - the needle to find */
/* nee_len - the length of the needle */
/* Return : position in haystack (0 based) or (-1) if no needle */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
for (i=0;i<(hay_len-nee_len+1);i++)
if (memcmpi(haystack+i,needle,nee_len) == 0)
return(i);
return(-1);
}
/***********************************************************************/
#ifdef PROTO
short memcmpi(unsigned char *buf1,unsigned char *buf2,short len)
#else
short memcmpi(buf1,buf2,len)
unsigned char *buf1,*buf2;
short len;
#endif
/***********************************************************************/
/* Function : Compares two memory buffers for equality; */
/* case insensitive. Same as memicmp() Microsoft C. */
/* Parameters: buf1 - first buffer */
/* buf2 - second buffer */
/* len - number of characters to compare. */
/* Return : <0 if buf1 < buf2, */
/* =0 if buf1 = buf2, */
/* >0 if buf1 > buf2, */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
#ifdef SUN
for(i=0;i<len;i++)
{
unsigned char c1,c2;
if (isupper(*buf1))
c1 = tolower(*buf1);
else
c1 = *buf1;
if (isupper(*buf2))
c2 = tolower(*buf2);
else
c2 = *buf2;
if (c1 != c2)
return(c1-c2);
++buf1;
++buf2;
}
#else
for(i=0;i<len;i++)
{
if (tolower(*buf1) != tolower(*buf2))
return tolower(*buf1) - tolower(*buf2);
++buf1;
++buf2;
}
#endif
return(0);
}
/*man***************************************************************************
NAME
equal - determine if strings are equal up to specified length
SYNOPSIS
unsigned short equal(con,str,min_len)
char *con,*str;
short min_len;
DESCRIPTION
The equal function determines if a two strings are equal, irrespective
of case, up to the length of the second string. The length of the
string must be greater than or equal to the specified minimum length.
RETURN VALUE
If 'equal' TRUE else FALSE.
*******************************************************************************/
#ifdef PROTO
unsigned short equal(unsigned char *con,unsigned char *str,short min_len)
#else
unsigned short equal(con,str,min_len)
unsigned char *con,*str;
short min_len;
#endif
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: equal");
#endif
if (memcmpi(con,str,min(strlen(str),strlen(con))) == 0
&& strlen(str) >= min_len
&& strlen(con) >= strlen(str))
{
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
/***********************************************************************/
#ifdef PROTO
int valid_integer(unsigned char *str)
#else
int valid_integer(str)
unsigned char *str;
#endif
/***********************************************************************/
/* Function : Checks that string contains only 0-9,- or +. */
/* Parameters: *str - string to be checked */
/* Return : YES or NO */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
int num_signs=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: valid_integer");
#endif
for (i=0; i<strlen(str); i++)
{
if (*(str+i) == '-' || *(str+i) == '+')
num_signs++;
else
if (!isdigit(*(str+i)))
{
#ifdef TRACE
trace_return();
#endif
return(NO);
}
}
if (num_signs > 1)
{
#ifdef TRACE
trace_return();
#endif
return(NO);
}
#ifdef TRACE
trace_return();
#endif
return(YES);
}
/***********************************************************************/
#ifdef PROTO
int valid_positive_integer(unsigned char *str)
#else
int valid_positive_integer(str)
unsigned char *str;
#endif
/***********************************************************************/
/* Function : Checks that string contains only 0-9, or +. */
/* Parameters: *str - string to be checked */
/* Return : YES or NO */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
int num_signs=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: valid_positive_integer");
#endif
for (i=0; i<strlen(str); i++)
{
if (*(str+i) == '+')
num_signs++;
else
if (!isdigit(*(str+i)))
{
#ifdef TRACE
trace_return();
#endif
return(NO);
}
}
if (num_signs > 1)
{
#ifdef TRACE
trace_return();
#endif
return(NO);
}
#ifdef TRACE
trace_return();
#endif
return(YES);
}
/***********************************************************************/
#ifdef PROTO
int strzeq(unsigned char *str,unsigned char ch)
#else
int strzeq(str,ch)
unsigned char *str;
char ch;
#endif
/***********************************************************************/
/* Function : Locate in ASCIIZ string, character */
/* Parameters: *str - string to be searched */
/* ch - character to be searched for */
/* Return : position in string of character - (-1) if not found */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int len;
register int i = 0;
/*--------------------------- processing ------------------------------*/
len = strlen(str);
for (; i<len && str[i]!=ch; i++);
if (i>=len)
i = (-1);
return(i);
}
/***********************************************************************/
#ifdef PROTO
LINE *ll_add(LINE *first,LINE *curr,unsigned short size)
#else
LINE *ll_add(first,curr,size)
LINE *first;
LINE *curr;
unsigned short size;
#endif
/***********************************************************************/
/* Adds a LINE to the current linked list after the current member. */
/* PARAMETERS: */
/* first - pointer to first LINE in linked list */
/* curr - pointer to current LINE in linked list */
/* size - size of a LINE item */
/* RETURN: - pointer to next LINE item */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *next=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: ll_add");
#endif
if ((next=(LINE *)memMalloc(size,"ll_add LINE *")) != NULL)
{
if (curr == NULL)
{
first = next;
next->next = NULL;
}
else
{
if (curr->next != NULL)
curr->next->prev = next;
next->next = curr->next;
curr->next = next;
}
next->prev = curr;
}
#ifdef TRACE
trace_return();
#endif
return(next);
}
/***********************************************************************/
#ifdef PROTO
LINE *ll_del(LINE *first,LINE *curr,char direction)
#else
LINE *ll_del(first,curr,direction)
LINE *first;
LINE *curr;
char direction;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *new_curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: ll_del");
#endif
/*---------------------------------------------------------------------*/
/* Delete the only record */
/*---------------------------------------------------------------------*/
if (curr->prev == NULL && curr->next == NULL)
{
memFree((void *)curr->line,curr->line);
memFree((void *)curr,"ll_del curr only");
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
/*---------------------------------------------------------------------*/
/* Delete the first record */
/*---------------------------------------------------------------------*/
if (curr->prev == NULL)
{
curr->next->prev = NULL;
new_curr = first = curr->next;
memFree((void *)curr->line,curr->line);
memFree((void *)curr,"ll_del curr first");
curr = new_curr;
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/*---------------------------------------------------------------------*/
/* Delete the last record */
/*---------------------------------------------------------------------*/
if (curr->next == NULL)
{
curr->prev->next = NULL;
new_curr = curr->prev;
memFree((void *)curr->line,curr->line);
memFree((void *)curr,"ll_del curr last");
curr = new_curr;
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/*---------------------------------------------------------------------*/
/* All others */
/*---------------------------------------------------------------------*/
curr->prev->next = curr->next;
curr->next->prev = curr->prev;
if (direction == DIRECTION_FORWARD)
new_curr = curr->next;
else
new_curr = curr->prev;
memFree((void *)curr->line,curr->line);
memFree((void *)curr,"ll_del curr");
curr = new_curr;
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/***********************************************************************/
#ifdef PROTO
void ll_free(LINE *first)
#else
void ll_free(first)
LINE *first;
#endif
/***********************************************************************/
/* Free up all allocated memory until the last item in the linked-list */
/* PARAMETERS: */
/* first - pointer to first line for the file */
/* RETURN: - void */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: ll_free");
#endif
curr = first;
while(curr != NULL)
{
memFree((void *)curr->line,curr->line);
memFree((void *)curr,"ll_free curr");
curr = curr->next;
}
/*---------------------------------------------------------------------*/
/* Free up the memory associated with the last item in the linked-list */
/*---------------------------------------------------------------------*/
/* memFree((void *)curr->line,curr->line);
memFree((void *)curr,"ll_free curr last"); */
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
LINE *ll_find(LINE *first,unsigned long row)
#else
LINE *ll_find(first,row)
LINE *first;
unsigned long row;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
long i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: ll_find");
#endif
curr = first;
if (curr != NULL)
for(i=0L;i<row && curr->next != NULL; i++, curr=curr->next);
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/***********************************************************************/
#ifdef PROTO
LINE *add_line(LINE *first,LINE *curr,unsigned char *line,
unsigned short len)
#else
LINE *add_line(first,curr,line,len)
LINE *first;
LINE *curr;
unsigned char *line;
unsigned short len;
#endif
/***********************************************************************/
/* Adds a member of the linked list for the specified file containing */
/* the line contents and length. */
/* PARAMETERS: */
/* first - pointer to first line for the file */
/* curr - pointer to current line for the file */
/* line - contents of line to be added */
/* len - length of line to be added */
/* RETURN: - pointer to current item in linked list or NULL if error*/
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: add_line");
#endif
next_line = ll_add(first,curr,sizeof(LINE));
if (next_line == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
curr_line = next_line;
curr_line->line = (unsigned char *)memMalloc((len+1)*sizeof(unsigned char),line);
if (curr_line->line == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
memcpy(curr_line->line,line,len);
*(curr_line->line+len) = '\0'; /* for functions that expect ASCIIZ string */
curr_line->length = len;
#ifdef TRACE
trace_return();
#endif
return(curr_line);
}
/***********************************************************************/
#ifdef PROTO
VIEW_DETAILS *vll_add(VIEW_DETAILS *first,VIEW_DETAILS *curr,unsigned short size)
#else
VIEW_DETAILS *vll_add(first,curr,size)
VIEW_DETAILS *first;
VIEW_DETAILS *curr;
unsigned short size;
#endif
/***********************************************************************/
/* Adds a VIEW_DETAILS to the current linked list after the current member. */
/* PARAMETERS: */
/* first - pointer to first VIEW_DETAILS in linked list */
/* curr - pointer to current VIEW_DETAILS in linked list */
/* size - size of a VIEW_DETAILS item */
/* RETURN: - pointer to next VIEW_DETAILS item */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
VIEW_DETAILS *next=(VIEW_DETAILS *)NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: vll_add");
#endif
if ((next=(VIEW_DETAILS *)memMalloc(size,"vll_add VIEW_DETAILS *")) != (VIEW_DETAILS *)NULL)
{
if (curr == (VIEW_DETAILS *)NULL)
{
first = next;
next->next = (VIEW_DETAILS *)NULL;
}
else
{
if (curr->next != (VIEW_DETAILS *)NULL)
curr->next->prev = next;
next->next = curr->next;
curr->next = next;
}
next->prev = curr;
}
#ifdef TRACE
trace_return();
#endif
return(next);
}
/***********************************************************************/
#ifdef PROTO
VIEW_DETAILS *vll_del(VIEW_DETAILS *first,VIEW_DETAILS *curr,char direction)
#else
VIEW_DETAILS *vll_del(first,curr,direction)
VIEW_DETAILS *first;
VIEW_DETAILS *curr;
char direction;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
VIEW_DETAILS *new_curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: vll_del");
#endif
/*---------------------------------------------------------------------*/
/* Delete the only record */
/*---------------------------------------------------------------------*/
if (curr->prev == (VIEW_DETAILS *)NULL && curr->next == (VIEW_DETAILS *)NULL)
{
memFree((void *)curr,"vll_del curr only");
#ifdef TRACE
trace_return();
#endif
first = curr = (VIEW_DETAILS *)NULL;
return((VIEW_DETAILS *)NULL);
}
/*---------------------------------------------------------------------*/
/* Delete the first record */
/*---------------------------------------------------------------------*/
if (curr->prev == (VIEW_DETAILS *)NULL)
{
curr->next->prev = (VIEW_DETAILS *)NULL;
new_curr = vd_first = curr->next;
memFree((void *)curr,"vll_del curr first");
curr = new_curr;
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/*---------------------------------------------------------------------*/
/* Delete the last record */
/*---------------------------------------------------------------------*/
if (curr->next == (VIEW_DETAILS *)NULL)
{
curr->prev->next = (VIEW_DETAILS *)NULL;
new_curr = curr->prev;
memFree((void *)curr,"vll_del curr last");
curr = new_curr;
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/*---------------------------------------------------------------------*/
/* All others */
/*---------------------------------------------------------------------*/
curr->prev->next = curr->next;
curr->next->prev = curr->prev;
if (direction == DIRECTION_FORWARD)
new_curr = curr->next;
else
new_curr = curr->prev;
memFree((void *)curr,"vll_del curr");
curr = new_curr;
#ifdef TRACE
trace_return();
#endif
return(curr);
}
/***********************************************************************/
#ifdef PROTO
long find_string(long start_line,short *start_col,char *needle,
short len,char direction,char offset,char kase)
#else
long find_string(start_line,start_col,needle,len,direction,offset,kase)
long start_line;
short *start_col;
char *needle;
short len;
char direction;
char offset;
char kase;
#endif
/***********************************************************************/
/* Finds a string from the line after/before the current line/col */
/* containing needle. Zone settings are considered as is case. */
/* PARAMETERS: */
/* start_line - current line number */
/* start_col - current column-offset from very beginning of buffer */
/* needle - string to search for */
/* len - length of needle (could contain nulls) */
/* direction - forward or backward */
/* value of 1 if forward, -1 if backward */
/* offset - offset from current line. For searches, this is the */
/* same as direction. For changes, this is 0. ie look at */
/* the current line before going on to the next/prev line.*/
/* kase - indicates if case is to be considered when matching */
/* RETURN: - TARGET_NOT_FOUND if not found */
/* - line number if found and column */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
long i;
short real_start,real_end,loc;
bool use_rec=FALSE;
unsigned char *ptr;
unsigned short haystack_len;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: find_string");
#endif
post_process_line(CURRENT_VIEW->focus_line);
if (len == 0)
use_rec = TRUE;
else
if (*(needle+(len-1)) == ' ')
use_rec = TRUE;
curr = ll_find(CURRENT_FILE->first_line,start_line+offset);
for (i=0;;i+=(long)direction)
{
if ((curr->next == NULL && direction == DIRECTION_FORWARD)
|| (curr->prev == NULL && direction == DIRECTION_BACKWARD))
break;
if (use_rec)
{
memset(rec,' ',MAX_LINE_LENGTH);
memcpy(rec,curr->line,curr->length);
ptr = rec;
haystack_len = MAX_LINE_LENGTH;
}
else
{
ptr = curr->line;
haystack_len = curr->length;
}
real_end = min(haystack_len,CURRENT_VIEW->zone_end-1);
real_start = max(*start_col,CURRENT_VIEW->zone_start-1);
if (kase == CASE_IGNORE)
loc = memposi(ptr+real_start,
(real_end - real_start + 1),needle,len);
else
loc = mempos(ptr+real_start,
(real_end - real_start + 1),needle,len);
if (loc != (-1))
{
*start_col = loc+real_start;
pre_process_line(CURRENT_VIEW->focus_line);
#ifdef TRACE
trace_return();
#endif
return(i+offset);
}
/*---------------------------------------------------------------------*/
/* Once we get here, we have gone on to a new line. For searches, the */
/* start_col has to be set back to 0 so that it can look from the */
/* beginning of a new line. */
/*---------------------------------------------------------------------*/
*start_col = 0;
if (direction == DIRECTION_FORWARD)
curr = curr->next;
else
curr = curr->prev;
}
#ifdef TRACE
trace_return();
#endif
pre_process_line(CURRENT_VIEW->focus_line);
return(TARGET_NOT_FOUND);
}
/***********************************************************************/
#ifdef PROTO
void put_char(WINDOW *win,chtype ch,char add_ins)
#else
void put_char(win,ch,add_ins)
WINDOW *win;
chtype ch;
char add_ins;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
chtype chr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: put_char");
#endif
chr = ch;
#if !defined(DOS) && !defined(OS2)
if (chr < ' ')
chr = ('@' + chr) | A_REVERSE;
#endif
if (add_ins == ADDCHAR)
waddch(win,chr);
else
winsch(win,chr);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void set_up_windows(void)
#else
void set_up_windows()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
unsigned char command_location;
extern short file_start;
extern unsigned char *dirfilename;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: set_up_windows");
#endif
if (CURRENT_VIEW->cmd_line == 'T') /* command top */
{
CURRENT_VIEW->command_row = CURRENT_SCREEN.origin_y+1;
command_location = 1;
}
else
{
CURRENT_VIEW->command_row = CURRENT_SCREEN.origin_y+CURRENT_SCREEN.screen_rows-1;
command_location = 0;
}
CURRENT_SCREEN.rows = CURRENT_SCREEN.screen_rows-2;
CURRENT_SCREEN.top_row = CURRENT_SCREEN.origin_y+1+command_location;
if (CURRENT_VIEW->prefix_on)
{
CURRENT_SCREEN.cols = CURRENT_SCREEN.screen_cols-PREFIX_WIDTH;
if (CURRENT_VIEW->prefix_left)
{
CURRENT_SCREEN.top_col = CURRENT_SCREEN.origin_x+PREFIX_WIDTH;
CURRENT_WINDOW_PREFIX = newwin(CURRENT_SCREEN.rows,PREFIX_WIDTH,
CURRENT_SCREEN.top_row,CURRENT_SCREEN.origin_x);
}
else
{
CURRENT_SCREEN.top_col = CURRENT_SCREEN.origin_x;
CURRENT_WINDOW_PREFIX = newwin(CURRENT_SCREEN.rows,PREFIX_WIDTH,
CURRENT_SCREEN.top_row,
CURRENT_SCREEN.origin_x+CURRENT_SCREEN.cols);
}
}
else
{
CURRENT_SCREEN.cols = CURRENT_SCREEN.screen_cols;
CURRENT_SCREEN.top_col = CURRENT_SCREEN.origin_x;
}
CURRENT_WINDOW_MAIN = newwin(CURRENT_SCREEN.rows,
CURRENT_SCREEN.cols,
CURRENT_SCREEN.top_row,
CURRENT_SCREEN.top_col);
CURRENT_WINDOW_COMMAND = newwin(1,CURRENT_SCREEN.screen_cols-PREFIX_WIDTH,
CURRENT_VIEW->command_row,
CURRENT_SCREEN.origin_x+PREFIX_WIDTH);
CURRENT_WINDOW_ARROW = newwin(1,PREFIX_WIDTH,
CURRENT_VIEW->command_row,
CURRENT_SCREEN.origin_x);
CURRENT_WINDOW_IDLINE = newwin(1,CURRENT_SCREEN.screen_cols,
CURRENT_SCREEN.origin_y,
CURRENT_SCREEN.origin_x);
wattrset(CURRENT_WINDOW_ARROW,colour[ATTR_ARROW]);
wattrset(CURRENT_WINDOW_MAIN,colour[ATTR_FILEAREA]);
wattrset(CURRENT_WINDOW_IDLINE,colour[ATTR_IDLINE]);
for (i=0;i<CURRENT_SCREEN.screen_cols;i++)
mvwaddch(CURRENT_WINDOW_IDLINE,0,i,' ');
#ifdef SUN
notimeout(CURRENT_WINDOW_MAIN,TRUE);
notimeout(CURRENT_WINDOW_COMMAND,TRUE);
#endif
wattrset(CURRENT_WINDOW_COMMAND,colour[ATTR_CMDLINE]);
wmove(CURRENT_WINDOW_COMMAND,0,0);
wclrtoeol(CURRENT_WINDOW_COMMAND);
if (CURRENT_VIEW->prefix_on)
{
#ifdef SUN
notimeout(CURRENT_WINDOW_PREFIX,TRUE);
#endif
wattrset(CURRENT_WINDOW_PREFIX,colour[ATTR_PREFIX]);
#if !defined(SUN) && !defined(VMS)
keypad(CURRENT_WINDOW_PREFIX,TRUE);
#endif
}
#if !defined(SUN) && !defined(VMS)
keypad(CURRENT_WINDOW_COMMAND,TRUE);
keypad(CURRENT_WINDOW_MAIN,TRUE);
#endif
CURRENT_VIEW->current_window = WINDOW_COMMAND;
CURRENT_VIEW->previous_window = WINDOW_MAIN;
mvwaddstr(CURRENT_WINDOW_ARROW,0,0,"====> ");
wnoutrefresh(CURRENT_WINDOW_ARROW);
wnoutrefresh(CURRENT_WINDOW_COMMAND);
if (strcmp(CURRENT_FILE->fname,dirfilename) == 0)
{
CURRENT_VIEW->focus_line++;
wmove(CURRENT_WINDOW_MAIN,CURRENT_VIEW->current_row,file_start-1);
}
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void delete_windows(void)
#else
void delete_windows()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: delete_windows");
#endif
if (CURRENT_VIEW->prefix_on)
delwin(CURRENT_WINDOW_PREFIX);
delwin(CURRENT_WINDOW_MAIN);
delwin(CURRENT_WINDOW_COMMAND);
delwin(CURRENT_WINDOW_IDLINE);
delwin(CURRENT_WINDOW_ARROW);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void pre_process_line(long line_number)
#else
void pre_process_line(line_number)
long line_number;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: pre_process_line");
#endif
curr = ll_find(CURRENT_FILE->first_line,line_number);
memset(rec,' ',MAX_LINE_LENGTH);
memcpy(rec,curr->line,curr->length);
rec_len = curr->length;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void post_process_line(long line_number)
#else
void post_process_line(line_number)
long line_number;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: post_process_line");
#endif
/*---------------------------------------------------------------------*/
/* Find the specified line in the linked list... */
/*---------------------------------------------------------------------*/
curr = ll_find(CURRENT_FILE->first_line,line_number);
/*---------------------------------------------------------------------*/
/* If the line hasn't changed, return. */
/*---------------------------------------------------------------------*/
if (rec_len == curr->length && (memcmp(rec,curr->line,curr->length) == 0))
{
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* Increment the alteration counters... */
/*---------------------------------------------------------------------*/
increment_alt();
/*---------------------------------------------------------------------*/
/* Add the old line contents to the line recovery list. */
/*---------------------------------------------------------------------*/
add_to_recovery_list(curr->line,curr->length);
/*---------------------------------------------------------------------*/
/* Realloc the dynamic memory for the line if the line is now longer. */
/*---------------------------------------------------------------------*/
if (rec_len > curr->length)
/* what if realloc fails ?? */
curr->line = (unsigned char *)memRealloc((void *)curr->line,(rec_len+1)*sizeof(unsigned char),
"post_process_line realloc");
/*---------------------------------------------------------------------*/
/* Copy the contents of rec into the line. */
/*---------------------------------------------------------------------*/
memcpy(curr->line,rec,rec_len);
curr->length = rec_len;
*(curr->line+rec_len) = '\0';
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
short blank_field(unsigned char *field)
#else
short blank_field(field)
unsigned char *field;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: blank_field");
#endif
if (strzne(field,' ') == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(TRUE); /* field is NULL or just contains spaces */
}
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
/***********************************************************************/
#ifdef PROTO
void adjust_marked_block(char insert_line,long base_line,long num_lines)
#else
void adjust_marked_block(insert_line,base_line,num_lines)
char insert_line;
long base_line;
long num_lines;
#endif
/***********************************************************************/
{
/*---------------------------------------------------------------------*/
/* When lines are deleted, the base line is the first line in the file */
/* irrespective of the direction that the delete is done. */
/*---------------------------------------------------------------------*/
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: adjust_marked_block");
#endif
if (MARK_VIEW != CURRENT_VIEW)
{
#ifdef TRACE
trace_return();
#endif
return;
}
switch(insert_line)
{
case YES:/* INSERT */
if (base_line < CURRENT_VIEW->mark_start_line)
{
CURRENT_VIEW->mark_start_line += num_lines;
CURRENT_VIEW->mark_end_line += num_lines;
break;
}
if (base_line >= CURRENT_VIEW->mark_start_line
&& base_line < CURRENT_VIEW->mark_end_line)
{
CURRENT_VIEW->mark_end_line += num_lines;
break;
}
break;
case NO: /* DELETE */
if (base_line <= CURRENT_VIEW->mark_start_line
&& base_line+num_lines >= CURRENT_VIEW->mark_end_line)
{
CURRENT_VIEW->mark_start_line = (-1);
CURRENT_VIEW->mark_end_line = (-1);
MARK_VIEW = (VIEW_DETAILS *)NULL;
break;
}
if (base_line+num_lines < CURRENT_VIEW->mark_start_line)
{
CURRENT_VIEW->mark_start_line -= num_lines;
CURRENT_VIEW->mark_end_line -= num_lines;
break;
}
if (base_line > CURRENT_VIEW->mark_end_line)
{
break;
}
if (base_line+num_lines > CURRENT_VIEW->mark_end_line)
{
CURRENT_VIEW->mark_end_line = base_line - 1;
break;
}
CURRENT_VIEW->mark_end_line -= num_lines;
break;
}
return;
#ifdef TRACE
trace_return();
#endif
}
/***********************************************************************/
#ifdef PROTO
char case_translate(char key)
#else
char case_translate(key)
char key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: case_translate");
#endif
if (CURRENT_VIEW->case_enter == CASE_UPPER
&& islower(key))
{
#ifdef TRACE
trace_return();
#endif
return(toupper(key));
}
if (CURRENT_VIEW->case_enter == CASE_LOWER
&& isupper(key))
{
#ifdef TRACE
trace_return();
#endif
return(tolower(key));
}
#ifdef TRACE
trace_return();
#endif
return(key);
}
/***********************************************************************/
#ifdef PROTO
void add_to_recovery_list(char *line,int len)
#else
void add_to_recovery_list(line,len)
char *line;
int len;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: add_to_recovery_list");
#endif
/*---------------------------------------------------------------------*/
/* Ignore empty lines. */
/*---------------------------------------------------------------------*/
if (len == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* First time through, set length array to (-1) to indicated unused. */
/* This setup MUST occur before the freeing up code. */
/*---------------------------------------------------------------------*/
if (add_recv == (-1))
{
for (i=0;i<MAX_RECV;i++)
recv_len[i] = (-1);
add_recv = 0; /* set to point to next available slot */
}
/*---------------------------------------------------------------------*/
/* Special case at end of program to free up dynamic memory allocated. */
/*---------------------------------------------------------------------*/
if (len == (-1) && line == NULL)
{
for (i=0;i<MAX_RECV;i++)
{
if (recv_len[i] != (-1))
free(recv[i]);
}
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* Now we are here, lets add to the array. */
/*---------------------------------------------------------------------*/
if (recv_len[add_recv] == (-1)) /* haven't malloced yet */
{
if ((recv[add_recv] = (unsigned char *)memMalloc((len+1)*sizeof(char),"add_to_recovery")) == NULL)
{
display_error(30,(unsigned char *)"");
#ifdef TRACE
trace_return();
#endif
return;
}
}
else
{
if ((recv[add_recv] = (unsigned char *)memRealloc(recv[add_recv],(len+1)*sizeof(char),"add to recovery")) == NULL)
{
display_error(30,(unsigned char *)"");
#ifdef TRACE
trace_return();
#endif
return;
}
}
memcpy(recv[add_recv],line,len);
recv_len[add_recv] = len;
retr_recv = add_recv;
add_recv = (++add_recv >= MAX_RECV) ? 0 : add_recv;
num_recv = (++num_recv > MAX_RECV) ? MAX_RECV : num_recv;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void get_from_recovery_list(int num)
#else
void get_from_recovery_list(num)
int num;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
int num_retr = min(num,num_recv);
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: get_from_recovery_list");
#endif
/*---------------------------------------------------------------------*/
/* Return error if nothing to recover. */
/*---------------------------------------------------------------------*/
if (retr_recv == (-1))
{
display_error(0,(unsigned char *)"0 line(s) recovered");
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* Retrieve each allocated recovery line and put back into the body. */
/*---------------------------------------------------------------------*/
for (i=0;i<num_retr;i++)
{
if (recv_len[retr_recv] != (-1))
{
insert_new_line(recv[retr_recv],recv_len[retr_recv],1L,TRUE);
retr_recv = (--retr_recv < 0) ? num_recv-1 : retr_recv;
}
}
sprintf(temp_cmd,"%d line(s) recovered",num_retr);
display_error(0,(unsigned char *)temp_cmd);
#ifdef TRACE
trace_return();
#endif
return;
}
#ifdef DOS
/***********************************************************************/
void draw_cursor(void)
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: draw_cursor");
#endif
if (mode_insert)
if (get_mode() == 7)
csr_size(5,13);
else
csr_size(3,7);
else
if (get_mode() == 7)
csr_size(12,13);
else
csr_size(6,7);
#ifdef TRACE
trace_return();
#endif
return;
}
#endif
#ifdef OS2
/***********************************************************************/
void draw_cursor(void)
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("util.c: draw_cursor");
#endif
if (mode_insert)
_set_cursor_mode(5,13);
else
_set_cursor_mode(12,13);
#ifdef TRACE
trace_return();
#endif
return;
}
#endif